"""
AI Agent Pro - 认证API端点
"""

from datetime import timedelta
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from slowapi import Limiter
from slowapi.util import get_remote_address

from app.auth.security import (
    AuthService, TokenManager, ApiKeyManager, PasswordManager,
    LoginRequest, RegisterRequest, PasswordChangeRequest, PasswordResetRequest,
    ApiKeyCreateRequest, ApiKeyResponse, Token,
    get_current_user, require_permission, Permission
)
from app.core.database import get_db
from app.core.logging import get_logger, log_security_event
from app.models import UserResponse, UserCreate

logger = get_logger(__name__)
router = APIRouter()

# 限流器
limiter = Limiter(key_func=get_remote_address)


@router.post("/register", response_model=dict, status_code=status.HTTP_201_CREATED)
@limiter.limit("5/minute")
async def register(
    user_data: RegisterRequest,
    db = Depends(get_db)
):
    """
    用户注册
    
    - **username**: 用户名 (3-50字符)
    - **email**: 邮箱地址
    - **password**: 密码 (至少6字符)
    - **full_name**: 全名 (可选)
    """
    try:
        user, access_token = await AuthService.register_user(db, user_data)
        
        return {
            "message": "注册成功",
            "user": {
                "id": user.id,
                "username": user.username,
                "email": user.email,
                "full_name": user.full_name
            },
            "access_token": access_token,
            "token_type": "bearer"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"用户注册失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="注册失败，请稍后重试"
        )


@router.post("/login", response_model=Token)
@limiter.limit("10/minute")
async def login(
    login_data: LoginRequest,
    db = Depends(get_db)
):
    """
    用户登录
    
    - **username**: 用户名
    - **password**: 密码
    - **remember_me**: 是否记住登录状态 (延长Token有效期)
    """
    try:
        token = await AuthService.login_user(db, login_data)
        return token
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"用户登录失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="登录失败，请稍后重试"
        )


@router.post("/token", response_model=Token)
@limiter.limit("10/minute")
async def login_for_access_token(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db = Depends(get_db)
):
    """
    OAuth2兼容的登录端点
    用于支持标准的OAuth2客户端
    """
    login_data = LoginRequest(
        username=form_data.username,
        password=form_data.password,
        remember_me=False
    )
    
    return await login(login_data, db)


@router.post("/refresh", response_model=Token)
@limiter.limit("20/minute") 
async def refresh_token(
    current_user: dict = Depends(get_current_user),
    db = Depends(get_db)
):
    """
    刷新访问令牌
    """
    try:
        # 创建新的访问令牌
        access_token = TokenManager.create_access_token(
            data={
                "sub": current_user["id"],
                "username": current_user["username"],
                "permissions": current_user.get("permissions", [])
            }
        )
        
        return Token(
            access_token=access_token,
            token_type="bearer",
            expires_in=1440 * 60,  # 24小时
            user_id=current_user["id"],
            permissions=current_user.get("permissions", [])
        )
        
    except Exception as e:
        logger.error(f"令牌刷新失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="令牌刷新失败"
        )


@router.post("/logout")
async def logout(
    current_user: dict = Depends(get_current_user)
):
    """
    用户登出
    注意：JWT令牌是无状态的，真正的登出需要客户端删除令牌
    """
    log_security_event("USER_LOGOUT", user_id=current_user["id"])
    
    return {
        "message": "登出成功",
        "note": "请确保客户端已删除访问令牌"
    }


@router.get("/me", response_model=dict)
async def get_current_user_info(
    current_user: dict = Depends(get_current_user)
):
    """
    获取当前用户信息
    """
    return {
        "id": current_user["id"],
        "username": current_user["username"],
        "permissions": current_user.get("permissions", []),
        "is_active": current_user.get("is_active", True)
    }


@router.put("/change-password")
async def change_password(
    password_data: PasswordChangeRequest,
    current_user: dict = Depends(get_current_user),
    db = Depends(get_db)
):
    """
    修改密码
    
    - **current_password**: 当前密码
    - **new_password**: 新密码
    """
    try:
        await AuthService.change_password(db, current_user["id"], password_data)
        
        return {"message": "密码修改成功"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"密码修改失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="密码修改失败"
        )


@router.post("/forgot-password")
@limiter.limit("3/minute")
async def forgot_password(
    reset_data: PasswordResetRequest,
    db = Depends(get_db)
):
    """
    忘记密码 - 发送重置邮件
    
    - **email**: 注册邮箱
    """
    try:
        # 这里应该实现邮件发送逻辑
        logger.info(f"密码重置请求: {reset_data.email}")
        
        # 模拟发送重置邮件
        return {
            "message": "如果邮箱存在，重置链接已发送",
            "note": "请检查您的邮箱（包括垃圾邮件文件夹）"
        }
        
    except Exception as e:
        logger.error(f"密码重置请求失败: {str(e)}")
        # 不暴露具体错误信息
        return {
            "message": "如果邮箱存在，重置链接已发送"
        }


@router.post("/verify-email")
async def verify_email(
    token: str,
    db = Depends(get_db)
):
    """
    验证邮箱
    
    - **token**: 邮箱验证令牌
    """
    try:
        # 验证邮箱令牌
        # 这里应该实现邮箱验证逻辑
        
        return {"message": "邮箱验证成功"}
        
    except Exception as e:
        logger.error(f"邮箱验证失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="验证链接无效或已过期"
        )


# ====== API密钥管理 ======

@router.get("/api-keys", response_model=List[ApiKeyResponse])
async def list_api_keys(
    current_user: dict = Depends(get_current_user),
    db = Depends(get_db)
):
    """
    获取用户的API密钥列表
    """
    try:
        # 从数据库获取API密钥
        # 这里应该实现真实的查询逻辑
        
        # 模拟API密钥数据
        api_keys = [
            {
                "id": "key_1",
                "name": "开发环境密钥",
                "permissions": ["agent:read", "agent:execute"],
                "is_active": True,
                "last_used": None,
                "expires_at": None,
                "created_at": "2024-01-01T00:00:00"
            }
        ]
        
        return api_keys
        
    except Exception as e:
        logger.error(f"获取API密钥列表失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取API密钥失败"
        )


@router.post("/api-keys", response_model=ApiKeyResponse)
async def create_api_key(
    key_data: ApiKeyCreateRequest,
    current_user: dict = Depends(get_current_user),
    db = Depends(get_db)
):
    """
    创建新的API密钥
    
    - **name**: 密钥名称
    - **permissions**: 权限列表
    - **expires_days**: 过期天数 (可选)
    """
    try:
        # 验证权限
        user_permissions = current_user.get("permissions", [])
        
        # 检查用户是否有权限创建API密钥
        if not any(perm in user_permissions for perm in [Permission.USER_WRITE, Permission.SYSTEM_ADMIN]):
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权限创建API密钥"
            )
        
        # 验证请求的权限不超过用户权限
        for perm in key_data.permissions:
            if perm not in user_permissions and Permission.SYSTEM_ADMIN not in user_permissions:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"无权限分配权限: {perm}"
                )
        
        # 创建API密钥
        api_key, db_api_key = await ApiKeyManager.create_api_key(
            db, current_user["id"], key_data.name, 
            key_data.permissions, key_data.expires_days
        )
        
        log_security_event("API_KEY_CREATED", user_id=current_user["id"], key_name=key_data.name)
        
        return ApiKeyResponse(
            id=db_api_key.id,
            name=db_api_key.name,
            key=api_key,  # 只在创建时返回
            permissions=db_api_key.permissions,
            is_active=db_api_key.is_active,
            last_used=db_api_key.last_used,
            expires_at=db_api_key.expires_at,
            created_at=db_api_key.created_at
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建API密钥失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="创建API密钥失败"
        )


@router.delete("/api-keys/{key_id}")
async def delete_api_key(
    key_id: str,
    current_user: dict = Depends(get_current_user),
    db = Depends(get_db)
):
    """
    删除API密钥
    """
    try:
        # 验证密钥所有权
        # api_key = await db.get(ApiKey, key_id)
        
        # 模拟验证
        api_key = {"user_id": current_user["id"], "name": "测试密钥"}
        
        if not api_key or api_key["user_id"] != current_user["id"]:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="API密钥不存在"
            )
        
        # 删除密钥
        # await db.delete(api_key)
        # await db.commit()
        
        log_security_event("API_KEY_DELETED", user_id=current_user["id"], key_id=key_id)
        
        return {"message": "API密钥已删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除API密钥失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除API密钥失败"
        )


# ====== 密码强度检查 ======

@router.post("/check-password-strength")
async def check_password_strength(
    password: str
):
    """
    检查密码强度
    
    返回密码强度评估和改进建议
    """
    try:
        result = PasswordManager.check_password_strength(password)
        
        return {
            "strength": result["strength"],
            "score": result["score"],
            "max_score": 5,
            "checks": result["checks"],
            "suggestions": [s for s in result["suggestions"] if s is not None],
            "passed": result["strength"] in ["medium", "strong"]
        }
        
    except Exception as e:
        logger.error(f"密码强度检查失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="密码强度检查失败"
        )


# ====== 权限信息 ======

@router.get("/permissions")
async def get_available_permissions(
    current_user: dict = Depends(require_permission(Permission.SYSTEM_ADMIN))
):
    """
    获取可用权限列表 (仅管理员)
    """
    return {
        "permissions": {
            "user": [p for p in dir(Permission) if p.startswith("USER_")],
            "agent": [p for p in dir(Permission) if p.startswith("AGENT_")],
            "conversation": [p for p in dir(Permission) if p.startswith("CONVERSATION_")],
            "tool": [p for p in dir(Permission) if p.startswith("TOOL_")],
            "system": [p for p in dir(Permission) if p.startswith("SYSTEM_")]
        },
        "roles": Permission.ROLES
    }


@router.get("/session")
async def get_session_info(
    current_user: dict = Depends(get_current_user)
):
    """
    获取当前会话信息
    """
    return {
        "user": {
            "id": current_user["id"],
            "username": current_user["username"],
            "permissions": current_user.get("permissions", [])
        },
        "session": {
            "authenticated": True,
            "auth_method": "jwt",
            "timestamp": "2024-01-01T00:00:00"
        }
    }